package jp.sourceforge.akjrcp.dropsomething;


import java.io.File;
import java.util.ArrayList;
import java.util.List;

import jp.sourceforge.akjrcp.akj_betas.Akj_betasPlugin;
import jp.sourceforge.akjrcp.akj_betas.Messages;
import jp.sourceforge.akjrcp.dropsomething.FFMpegConvertTabBuilder.FFMpegConvertTab;
import jp.sourceforge.akjrcp.dropsomething.actions.MakePSPThumbnailAction;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegExecuter;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegOptions;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegUI;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegUtils;
import jp.sourceforge.akjrcp.psp.OldPSPSettingPage;
import jp.sourceforge.akjrcp.psp.PSPFFMpegPreference;
import jp.sourceforge.akjrcp.psp.PSPMovieSetting;
import jp.sourceforge.akjrcp.psp.PSPMovieSettingTableViewer;
import jp.sourceforge.akjrcp.psp.PSPSettingPage;
import jp.sourceforge.akjrcp.ui.FileOverwriteControler;
import jp.sourceforge.akjrcp.util.StatusBarUtils;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;

public class PSPConvertTabBuilder implements IDropSomething{

	private FileOverwriteControler fileOverwriteControler;
	
	public static final String TYPE_SELECT="type_select";
	
	public static final String AVISYNTH="avisynth";
	public static final String TWO_PASS="twopass";
	
	public static final String PSPCONVERT="pspconvert";
	
	//static is important
	private static String icon_xvid="icons/psp_xvid1.png";
	private  static String icon_xvid_hq="icons/psp_xvid3.png";

	
	private  static String icon_h264="icons/psp_h2641.png";

	private  static String icon_h264_hq="icons/psp_h2643.png";
	

	private DropsomethingTab dtab;
	private CTabItem tabItem1 ;
	
	public void createControl(final ViewPart part,final CTabFolder tab) {
		if(dtab==null){
			//deley create control
			dtab=new PSPConvertTab(tab,SWT.NULL);
			dtab.setViewPart(part);
			tabItem1.setControl(dtab);
		}
	}
	
	public void createTab(ViewPart part, CTabFolder tab) {
		 tabItem1 = new CTabItem(tab, SWT.NONE);
		tabItem1.setText(Messages.getString("pspconvert.tab_old"));
		
		
		
		
		fileOverwriteControler=new FileOverwriteControler(tab.getShell());
	}
	
	public class PSPConvertTab extends DirectoryBasedDropSomething implements FFMpegDropSomethingTab{

		private FFMpegExecuter ffmpegExecuter;

		private Label dragHere;

		

		private String currentTarget;
		
		//private List buttonList;
		
		private Button avisynth;
		private Button twoPass;
		
		public PSPConvertTab(Composite parent, int style) {
			super(parent, style);
			
			
		}

		private List settingList;

		private PSPMovieSettingTableViewer tableViewer;

		private Button fileChooser;
		public Composite createControls(Composite parent) {
			//buttonList=new ArrayList();
			settingList=new ArrayList();
			setPreferenceKey(PSPCONVERT);
			
			SavePreferenceStore savePreference=new SavePreferenceStore();
			Composite composite=new Composite(parent,SWT.NULL);
			composite.setLayout(new GridLayout(1,true));
			
			Composite pspDirectoryPanel=new Composite(composite,SWT.NULL);
			pspDirectoryPanel.setLayout(new GridLayout(2,false));
			Button pspFolder=new Button(pspDirectoryPanel,SWT.PUSH);
			pspFolder.setText(Messages.getString("pspcovert.exportpsp"));
			pspFolder.addSelectionListener(new SetPSPDir());
			
			createDirectoryInfo(composite);
			
			
	
			Composite typeGroup=new Composite(composite,SWT.NULL);
			typeGroup.setLayout(new GridLayout(4,false));
			
			
		
		    		
			
			
			
			
			
			
			
			
			List list=PSPMovieSettingTableViewer.loadList(getPreferenceStore().getString(OldPSPSettingPage.EXPORT_MOVIE_SETTINGS));
			log.info(list.size());
			
			for(int i=0;i<4&i<list.size();i++){
			PSPSettingComposite setting;
			
			setting=new PSPSettingComposite(typeGroup,SWT.NONE,(PSPMovieSetting) list.get(i),i);
			settingList.add(setting);
			
			}
			
			
			
			
		
			
			GridData gd = new GridData(GridData.FILL_BOTH);
			tableViewer = new PSPMovieSettingTableViewer(composite);
			tableViewer.getTable().setLayoutData(gd);
			tableViewer.setMovieSettingList(list);
			int defaultSelect=getPreferenceStore().getInt(OldPSPSettingPage.EXPORT_MOVIE_SETTINGS_INDEX);
			tableViewer.getTable().setSelection(defaultSelect);//default set
			tableViewer.addSelectionChangedListener(new StoreSelect());
			
			
			
			twoPass = new Button(composite, SWT.CHECK);
			twoPass.setText(Messages.getString("mpegconvert.twopass"));
			//twoPass.setSelection(getPreferenceStore().getBoolean(PREFERENCE_TWO_PASS));
			twoPass.setToolTipText(Messages
					.getString("mpegconvert.twopass_tooltip"));
			twoPass.addSelectionListener(savePreference);
			twoPass.setVisible(false);//now not support
			
			avisynth = new Button(composite, SWT.CHECK);
			avisynth.setText(Messages.getString("pspconvert.use_avisynth"));
			//avisynth.setSelection(getPreferenceStore().getBoolean(PREFERENCE_AVISAYNTH));
			avisynth.setToolTipText(Messages
					.getString("pspconvert.use_avisynth_tooltip"));
			avisynth.addSelectionListener(savePreference);
			
			
			//
			Composite dragHereComposite=new Composite(composite,SWT.NULL);
			dragHereComposite.setLayout(new GridLayout(2,false));
			dragHereComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			
			dragHere=new Label(dragHereComposite,SWT.NULL);
			dragHere.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			
			fileChooser = new Button(dragHereComposite,SWT.NULL);
			fileChooser.setText(Messages.getString("dropsomething.or_select_file"));
			fileChooser.addSelectionListener(new SelectionListener(){
				public void widgetDefaultSelected(SelectionEvent e) {
				}

				public void widgetSelected(SelectionEvent e) {
					FileDialog dialog=new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),SWT.MULTI);
					dialog.setFilterExtensions(new String[]{"*.avi;*.flv;*.mpg;*.wmv;*.avs;*.mp4;*.vob;*.mpeg"});
					String path=dialog.open();
					if(path!=null){
						if(isCanConvert()){
						File parent=new File(path).getParentFile();
						String paths[]=dialog.getFileNames();
						for (int i = 0; i < paths.length; i++) {
							addDragAndDropFile(new File(parent,paths[i]).getAbsolutePath());
						}
						}else{
						StatusBarUtils.showStatusBar(getCantConvertStatusbarMessage());	
						}
					}
				}});
			
			//restore controls
			
			
			
			IPreferenceStore store=getPreferenceStore();
			store.setDefault(getPreferenceKey()+"."+TYPE_SELECT,"h2642_2");//default
			String typeSelected=store.getString(getPreferenceKey()+"."+TYPE_SELECT);
			currentTarget=typeSelected;
			
			/*
			for (int i = 0; i < settingList.size(); i++) {
				PSPSettingComposite setting2=(PSPSettingComposite) settingList.get(i);
				//log.info(currentTarget+","+setting2.getKey());
				if(currentTarget.equals(setting2.getKey())){
					
					checkToRadio.select(setting2.getButton());
				}
			}*/
			
			/*
			for (int i = 0; i < settingList.size(); i++) {
				PSPSettingComposite setting2=(PSPSettingComposite) settingList.get(i);
				log.info(i+","+setting2.getSlected());
			}*/
			
			/*
			for(int i=0;i<buttonList.size();i++){
				Button bt=(Button) buttonList.get(i);
				String k=(String) bt.getData("key");
				if(typeSelected.equals(k)){
					bt.setSelection(true);
					
				}
			}*/
			log.info(getPreferenceKey()+"."+TYPE_SELECT+","+currentTarget);
		
			restoreControl(avisynth);
			restoreControl(twoPass);
			
			
			updateStatus();
			PlatformUI.getPreferenceStore().addPropertyChangeListener( new SettingMonitor());
			
			return composite;
		}
		
		public class SettingMonitor implements IPropertyChangeListener {

			public void propertyChange(PropertyChangeEvent event) {
				log.info(event.getProperty());
				if (event.getProperty().equals(FFMpegUI.FFMPEG_PATH)) {
					updateStatus();
				} 
			}
		}
		
		public class StoreSelect implements ISelectionChangedListener{

			public void selectionChanged(SelectionChangedEvent event) {
				getPreferenceStore().setValue(OldPSPSettingPage.EXPORT_MOVIE_SETTINGS_INDEX, tableViewer.getTable().getSelectionIndex());
			}
			
		}
		
public class SetPSPDir implements SelectionListener{

	public void widgetDefaultSelected(SelectionEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void widgetSelected(SelectionEvent e) {
		File roots[]=File.listRoots();
		for (int i = roots.length-1; i >0; i--) {
			File tmp=new File(roots[i],"PSP");
		if(tmp.exists()){
			File videoFolder=new File(roots[i],"VIDEO");
			if(videoFolder.exists()){
			directoryChooser.setEnabled(true);
			samefolder.setSelection(false);
			directoryChooser.setFile(videoFolder);
			updateStatus();
			}
			}
		}
		
	}
	
}
public class PSPSettingComposite extends Composite implements SelectionListener{


private Button checkbox;
private int tableIndex;

public boolean getSlected(){
	return checkbox.getSelection();
}
public Button getButton(){
	return checkbox;
}
	public PSPSettingComposite(Composite parent, int style,PSPMovieSetting setting,int tableIndex) {//TODO chenge talbeIndex
		super(parent, style);
		this.tableIndex=tableIndex;
	
		
		setLayout(new GridLayout(3,false));
		checkbox = new Button(this,SWT.NULL);
		//checkbox.addSelectionListener(checkToRadio);//check to radio
		checkbox.addSelectionListener(this);
		
		
		//Label iconLabel=new Label(this,SWT.NULL);
		String icon=null;
		if(setting.getVideoCodec()==PSPMovieSetting.XVID){
			if(setting.isHighQuality()){
				icon=icon_xvid_hq;
				
			}else{
				icon=icon_xvid;
			}
		}else{
			if(setting.isHighQuality()){
				icon=icon_h264_hq;
			}else{
			
				icon=icon_h264;
			}
		}
		checkbox.setImage(AbstractUIPlugin.imageDescriptorFromPlugin(
				Akj_betasPlugin.PLUGIN_ID, icon).createImage());
		
		//iconLabel.addMouseListener(this);
		
		Label infoLabel=new Label(this,SWT.NULL);
		String info="";
		info+=setting.getVideoSize()+" "+setting.getVideoBitrate()+"k "+"\n";
		info+=setting.getAudioRate()+"hz "+setting.getAudioBitrate()+"k"+"\n";
		info+=setting.getComment();
		
		infoLabel.setText(info);
		//infoLabel.addMouseListener(this);
	}
	

	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	public void mouseDoubleClick(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	public void mouseDown(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	public void mouseUp(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}


	
	public void widgetDefaultSelected(SelectionEvent e) {
		
	}

	public void widgetSelected(SelectionEvent e) {
		tableViewer.getTable().setSelection(tableIndex);
		tableViewer.getTable().setFocus();
		//store data TODO
	}
}


		
		
public class SavePreferenceStore implements SelectionListener{
			
			public void widgetDefaultSelected(SelectionEvent e) {
				
			}

			public void widgetSelected(SelectionEvent e) {
				storeControl((Control)e.getSource());
			}
		}
		
		public void restoreControl(Control control){
			IPreferenceStore store=getPreferenceStore();
			
			if(control==avisynth){
				
				avisynth.setSelection(store.getBoolean(getPreferenceKey()+"."+AVISYNTH));
				
				}else if(control==twoPass){
					
					twoPass.setSelection(store.getBoolean(getPreferenceKey()+"."+TWO_PASS));
				
					}

			
		}
		
		public void selectCombo(CCombo combo,String value){
			int s=combo.getItemCount();
			for (int i = 0; i <s; i++) {
				if(combo.getItem(i).equals(value)){
					combo.select(i);
					break;
				}
			}
		}
		

		public void storeControl(Control control){
			IPreferenceStore store=getPreferenceStore();
			
			if(control==avisynth){
				
				
				store.setValue(getPreferenceKey()+"."+AVISYNTH, avisynth.getSelection());
				}else if(control==twoPass){
					
					
					store.setValue(getPreferenceKey()+"."+TWO_PASS, twoPass.getSelection());
					}
		}
		

		
		
		public String toTime(long bps,long maxMega){
			long bytes=bps/8;
			
			long second=maxMega*1024*1024/bytes;
			long hour=second/3600;
			second=second%3600;
			long min=second/60;
			long sec=second%60;
			
			String hstring=""+hour;
			if(hstring.length()<2){
				hstring="0"+hstring;
			}
			
			String mstring=""+min;
			if(mstring.length()<2){
				mstring="0"+mstring;
			}
			
			String sstring=""+sec;
			if(sstring.length()<2){
				sstring="0"+sstring;
			}
			return hstring+":"+mstring+":"+sstring;
		}

		public void inconvert(File file) {
			ffmpegExecuter.execute(new File[]{file});
		}

		
		public void beforeConvert() {
			ffmpegExecuter = new FFMpegExecuter();
			
			DefaultFFMpegMonitor monitor=new DefaultFFMpegMonitor(this,"PSP");
			monitor.setAfterAction(new MakePSPThumbnailAction());
			//set after actions
			ffmpegExecuter.setExecuteListener(monitor);
			
			
			//int select=tableViewer.getTable().getSelectionIndex();
			//log.infoselect:"+select);
			PSPMovieSetting setting=(PSPMovieSetting) tableViewer.getMovieSettingList().get(tableViewer.getTable().getSelectionIndex());
			PSPFFMpegPreference preference=toPreference(setting);
			log.info("hq:"+preference.isH264HQ());
			setHeaderText(tableViewer.toLabel(setting));//TODO change generic base
			log.info(preference);
//			support thread.
			boolean threads = FFMpegUI.isUseThread();
			if(threads){
				preference.setThreads(2);
			}
			
			ffmpegExecuter.setFfmpegPreference(preference);
			ffmpegExecuter.setUseAvisynth(avisynth.getSelection());
			ffmpegExecuter.setIgnoreAvisynthExtensions(new String[0]);//depend on
			
			
			ffmpegExecuter.setSameDirectory(samefolder.getSelection());
			ffmpegExecuter.setBackup(backup.getSelection());
			if(!samefolder.getSelection()){
				ffmpegExecuter.setExportDir(directoryChooser.getAbsoluteFilePath());
			}
			
			
				
			
			
		
			
			
			
		}
		


		public void afterConvert() {
			// TODO Auto-generated method stub
			
		}
		
		//overwrite only work when ffmpeg is available
		public boolean isCanConvert(){
			
			String ffmpegPath = FFMpegUI.getFFmpeg();

			if (!FFMpegUtils.isFFMpegAvailable(ffmpegPath)) {
			setCantConvertStatusbarMessage(Messages.getString("ffmpeg_statusbar.no_ffmpeg"));
			return false;
			}
			return super.isCanConvert();
		}

		public void cancelConvert() {
			ffmpegExecuter.cancel();
		}

		public void updateStatus() {
			
			
				
			
			if(samefolder.getSelection() || directoryChooser.getFile()!=null){
				setMessage(Messages.getString("dropsomething.drag_folder"));
				setCanConvert(true);
			}else{
				setErrorMessage(Messages.getString("dropsomething.choose_folder"));
				setCantConvertStatusbarMessage(Messages.getString("dropsomething.choose_folder"));
				setCanConvert(false);
			}
			
			
			
			if (!FFMpegUtils.isFFMpegAvailable(FFMpegUI.getFFmpeg())) {
				setErrorMessage(Messages.getString("dropsomething.setup_ffmpeg"));
				}
			
			
			if(fileChooser!=null){
				fileChooser.setEnabled(isCanConvert());
			}
		}
		
		public void setMessage(String text){
			if(dragHere!=null){//before initialize
			dragHere.setForeground(new Color(null,64,200,64));
			dragHere.setText(text);
			}
		}
		public void setErrorMessage(String text){
			if(dragHere!=null){
			dragHere.setForeground(new Color(null,255,0,0));
			dragHere.setText(text);
			}
		}

		public IPreferenceStore getPreferenceStore(){
			return Akj_betasPlugin.getDefault().getPreferenceStore();
		}
		
		public boolean setFocus(){
			return tableViewer.getTable().setFocus();
			
		}

		public FFMpegExecuter getFFMpegExecuter() {
			return ffmpegExecuter;
		}

		public FileOverwriteControler getFileOverWriteControler() {
			return fileOverwriteControler;
		}

		
		
	}
	

	public static PSPFFMpegPreference toPreference(PSPMovieSetting setting){
		PSPFFMpegPreference preference=new PSPFFMpegPreference();
		String ffmpegPath = FFMpegUI.getFFmpeg();
		preference.setFfmpegPath(ffmpegPath);
		
		preference.setFlags(new String[]{FFMpegOptions.FLAGS_BITEXACT});//maybe need it.
		
		preference.setExtension(FFMpegOptions.EXTENSION_MP4);
		preference.setFormat(FFMpegOptions.FORMAT_PSP);
		preference.setCoder(1);//must 
		
		
		//
		if(setting.getVideoCodec()==PSPMovieSetting.H264){
			preference.setVideoCodec(FFMpegOptions.CODEC_VIDEO_H264);
			preference.setH264HQ(setting.isHighQuality());
			preference.setLevel(FFMpegOptions.LEVEL_21);
		}else{
			preference.setVtag(FFMpegOptions.TAG_MP4VIDEO);
			preference.setVideoCodec(FFMpegOptions.CODEC_VIDEO_XVID);
			preference.setVideoAspect(FFMpegOptions.ASPECT_4x3);
			//xvid hq
		}
		
		preference.setVideoBitrate(setting.getVideoBitrate()-8);//magic number.
		preference.setMaxRate(setting.getVideoBitrate());
		preference.setBufSize(setting.getVideoBitrate());
		
		if(setting.getVideoCodec()==PSPMovieSetting.H264){
			
			
		}
		
		
		preference.setVideoRate(setting.getVideoRate());
		preference.setVideoSize(setting.getVideoSize());
		if(setting.getVideoSize().equals(PSPMovieSetting.SIZE_368x272)){
			//need it.//is is work?
			//preference.setVideoAspect(FFMpegPreference.VIDEO_ASPECT_4x3);//useless?
			
			preference.setLevel(FFMpegOptions.LEVEL_30);
		}else if(setting.getVideoSize().equals(PSPMovieSetting.SIZE_720x480)){
			preference.setLevel(FFMpegOptions.LEVEL_30);
		}else if(setting.getVideoSize().equals(PSPMovieSetting.SIZE_480x272)){
			preference.setLevel(FFMpegOptions.LEVEL_30);
		}else if(setting.getVideoSize().equals(PSPMovieSetting.SIZE_352x480)){
			preference.setLevel(FFMpegOptions.LEVEL_30);
		}
		
		if(preference.getLevel()==FFMpegOptions.LEVEL_30){
			if(setting.getVideoBitrate()==PSPMovieSetting.BITRATE_768){
				
				preference.setMaxRate(FFMpegOptions.BITRATE_MAX_LEVEL21_4000);
				preference.setBufSize(FFMpegOptions.BITRATE_MAX_LEVEL21_4000);
				
			}else if(setting.getVideoBitrate()==PSPMovieSetting.BITRATE_1536){
				
				preference.setMaxRate(FFMpegOptions.BITRATE_MAX_LEVEL30_10000);
				preference.setBufSize(FFMpegOptions.BITRATE_MAX_LEVEL30_10000);
				
			}
		}
		
		preference.setAudioCodec(FFMpegOptions.CODEC_AUDIO_AAC);
		preference.setAudioBitrate(setting.getAudioBitrate());
		preference.setAudioRate(setting.getAudioRate());
		preference.setAudioChannel(setting.getAudioChannel());
		
		return preference;
	}
	
}
